<template>
  <!-- 树形数据编辑器对话框 -->
  <el-dialog
    v-model="visible"
    :title="dialogTitle"
    width="80%"
    :close-on-click-modal="false"
    @update:model-value="handleVisibleChange"
  >
    <div class="tree-data-editor">
      <div
        class="editor-content"
        style="display: flex; gap: 16px; height: 400px"
      >
        <!-- 左侧格式说明 -->
        <div
          class="data-format-tip"
          style="flex: 1; overflow-y: auto; padding-right: 8px"
        >
          <h4>{{ t("formDesigner.propertyPanel.tree.dataFormatTitle") }}</h4>
          <template v-if="treeType === 'tree'">
            <p>• {{ t("formDesigner.propertyPanel.tree.dataFormatRule1") }}</p>
            <p
              v-html="
                '• ' + t('formDesigner.propertyPanel.tree.dataFormatRule2Tree')
              "
            ></p>
            <p
              v-html="
                '• ' + t('formDesigner.propertyPanel.tree.dataFormatRule4')
              "
            ></p>
            <p
              v-html="
                '• ' + t('formDesigner.propertyPanel.tree.dataFormatRule5')
              "
            ></p>
          </template>
          <template v-if="treeType === 'treeselect' || treeType === 'cascader'">
            <p>• {{ t("formDesigner.propertyPanel.tree.dataFormatRule1") }}</p>
            <p
              v-html="
                '• ' + t('formDesigner.propertyPanel.tree.dataFormatRule2Other')
              "
            ></p>
            <p
              v-html="
                '• ' + t('formDesigner.propertyPanel.tree.dataFormatRule3Other')
              "
            ></p>
            <p
              v-html="
                '• ' + t('formDesigner.propertyPanel.tree.dataFormatRule4')
              "
            ></p>
            <p
              v-if="treeType === 'cascader'"
              v-html="
                '• ' + t('formDesigner.propertyPanel.tree.dataFormatRule5')
              "
            ></p>
          </template>
          <!-- <template v-if="treeType === 'cascader'"> </template> -->
          <template v-if="treeType === 'descriptions'">
            <p
              v-html="
                '• ' +
                t('formDesigner.propertyPanel.descriptions.dataFormatRule1')
              "
            ></p>
            <p
              v-html="
                '• ' +
                t('formDesigner.propertyPanel.descriptions.dataFormatRule2')
              "
            ></p>
            <p
              v-html="
                '• ' +
                t('formDesigner.propertyPanel.descriptions.dataFormatRule3')
              "
            ></p>
            <p
              v-html="
                '• ' +
                t('formDesigner.propertyPanel.descriptions.dataFormatRule4')
              "
            ></p>
            <p
              v-html="
                '• ' +
                t('formDesigner.propertyPanel.descriptions.dataFormatRule5')
              "
            ></p>
          </template>
          <p>• {{ t("formDesigner.propertyPanel.tree.exampleFormat") }}</p>
          <pre class="format-example" v-if="treeType === 'tree'">
[
  {
    "id": 1,
    "label": "{{ t("formDesigner.propertyPanel.tree.exampleNodeName") }}",
    "children": [
      {
        "id": 11,
        "label": "{{ t("formDesigner.propertyPanel.tree.exampleChildNode") }}"
      }
    ]
  }
]</pre
          >
          <pre
            class="format-example"
            v-if="treeType === 'treeselect' || treeType === 'cascader'"
          >
[
  {
    "label": "{{ t("formDesigner.propertyPanel.tree.exampleNodeName") }}",
    "value": 1,
    "children": [
      {
        "label": "{{ t("formDesigner.propertyPanel.tree.exampleChildNode") }}",
        "value": 11
      }
    ]
  }
]</pre
          >
          <pre class="format-example" v-if="treeType === 'descriptions'">
[
  {
    "label": "{{
              t("formDesigner.propertyPanel.descriptions.exampleUsername")
            }}",
    "value": "{{
              t("formDesigner.propertyPanel.descriptions.exampleUsernameValue")
            }}",
    "span": 1
  },
  {
    "label": "{{ t("formDesigner.propertyPanel.descriptions.examplePhone") }}",
    "value": "{{
              t("formDesigner.propertyPanel.descriptions.examplePhoneValue")
            }}",
    "span": 1
  },
  {
    "label": "{{
              t("formDesigner.propertyPanel.descriptions.exampleAddress")
            }}",
    "value": "{{
              t("formDesigner.propertyPanel.descriptions.exampleAddressValue")
            }}",
    "span": 2,
    "align": "left"
  },
  {
    "label": "{{ t("formDesigner.propertyPanel.descriptions.exampleRemark") }}",
    "value": "{{
              t("formDesigner.propertyPanel.descriptions.exampleRemarkValue")
            }}",
    "span": 3,
    "className": "custom-class"
  }
]</pre
          >
        </div>
        <!-- 右侧JSON输入框 -->
        <div style="flex: 1; display: flex; flex-direction: column">
          <div style="margin-bottom: 8px; display: flex; gap: 8px">
            <el-button size="small" @click="formatJson">{{
              t("formDesigner.propertyPanel.tree.formatJson")
            }}</el-button>
            <el-button size="small" @click="compressJson">{{
              t("formDesigner.propertyPanel.tree.compressJson")
            }}</el-button>
            <el-button size="small" @click="validateJson">{{
              t("formDesigner.propertyPanel.tree.validateJson")
            }}</el-button>
            <el-button type="primary" size="small" @click="resetTreeData">{{
              t("formDesigner.propertyPanel.tree.useExampleData")
            }}</el-button>
          </div>
          <div class="json-editor-container">
            <!-- 行号显示区域 -->
            <div class="line-numbers" ref="lineNumbersRef">
              <div
                v-for="lineNumber in lineNumbers"
                :key="lineNumber"
                class="line-number"
              >
                {{ lineNumber }}
              </div>
            </div>
            <!-- JSON输入区域 -->
            <textarea
              v-model="jsonText"
              :placeholder="
                t('formDesigner.propertyPanel.tree.jsonPlaceholder')
              "
              class="json-textarea"
              ref="textareaRef"
              @keydown="handleJsonKeydown"
              @scroll="handleTextareaScroll"
              @input="updateLineNumbers"
            ></textarea>
          </div>
          <div
            v-if="validationMessage"
            class="json-validation"
            :class="validationClass"
          >
            {{ validationMessage }}
          </div>
        </div>
      </div>
    </div>
    <template #footer>
      <el-button @click="handleCancel">{{
        t("formDesigner.propertyPanel.tree.cancel")
      }}</el-button>
      <el-button type="primary" @click="handleSave">{{
        t("formDesigner.propertyPanel.tree.save")
      }}</el-button>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, computed, watch } from "vue";
import { ElMessage } from "element-plus";
import { useI18n } from "vue-i18n";

// 国际化
const { t } = useI18n();

// Props
const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false,
  },
  treeType: {
    type: String,
    default: "tree",
  },
  jsonData: {
    type: String,
    default: "",
  },
});

// Emits
const emit = defineEmits(["update:modelValue", "save"]);

// 响应式数据
const visible = ref(false);
const jsonText = ref("");
const validationMessage = ref("");
const validationClass = ref("");
const lineNumbers = ref([1]);
const textareaRef = ref(null);
const lineNumbersRef = ref(null);

// 计算属性
const dialogTitle = computed(() => {
  let typeText = "";
  if (props.treeType === "tree") {
    typeText = t("formDesigner.propertyPanel.tree.treeControl");
  } else if (props.treeType === "treeselect") {
    typeText = t("formDesigner.propertyPanel.tree.treeSelect");
  } else if (props.treeType === "cascader") {
    typeText = t("formDesigner.propertyPanel.tree.cascader");
  } else if (props.treeType === "descriptions") {
    typeText = t("formDesigner.propertyPanel.tree.descriptions");
  }

  return t("formDesigner.propertyPanel.tree.configDialogTitle", {
    type: typeText,
  });
});

// 监听props变化
watch(
  () => props.modelValue,
  (newVal) => {
    visible.value = newVal;
  },
  { immediate: true }
);

// 行号相关方法
const updateLineNumbers = () => {
  const lines = jsonText.value.split("\n");
  lineNumbers.value = Array.from({ length: lines.length }, (_, i) => i + 1);
};

const handleTextareaScroll = () => {
  if (textareaRef.value && lineNumbersRef.value) {
    lineNumbersRef.value.scrollTop = textareaRef.value.scrollTop;
  }
};

watch(
  () => props.jsonData,
  (newVal) => {
    jsonText.value = newVal;
    updateLineNumbers();
  },
  { immediate: true }
);

// 监听jsonText变化更新行号
watch(
  () => jsonText.value,
  () => {
    updateLineNumbers();
  }
);

// 处理可见性变化
const handleVisibleChange = (value) => {
  emit("update:modelValue", value);
};

// JSON编辑器相关方法
const handleJsonKeydown = (event) => {
  // 处理Tab键缩进
  if (event.key === "Tab") {
    event.preventDefault();
    const textarea = event.target;
    const start = textarea.selectionStart;
    const end = textarea.selectionEnd;
    const value = textarea.value;

    if (event.shiftKey) {
      // Shift+Tab 减少缩进
      const lineStart = value.lastIndexOf("\n", start - 1) + 1;
      const lineText = value.substring(lineStart, start);
      if (lineText.startsWith("  ")) {
        textarea.value =
          value.substring(0, lineStart) +
          lineText.substring(2) +
          value.substring(start);
        textarea.selectionStart = textarea.selectionEnd = start - 2;
      }
    } else {
      // Tab 增加缩进
      textarea.value = value.substring(0, start) + "  " + value.substring(end);
      textarea.selectionStart = textarea.selectionEnd = start + 2;
    }
    jsonText.value = textarea.value;
  }

  // 处理回车自动缩进
  if (event.key === "Enter") {
    event.preventDefault();
    const textarea = event.target;
    const start = textarea.selectionStart;
    const end = textarea.selectionEnd;
    const value = textarea.value;
    const lineStart = value.lastIndexOf("\n", start - 1) + 1;
    const currentLine = value.substring(lineStart, start);
    const indent = currentLine.match(/^\s*/)[0];

    // 检查光标前后的字符
    const charBefore = value.charAt(start - 1);
    const charAfter = value.charAt(start);

    // 检查是否在括号中间
    const isInBrackets =
      (charBefore === "{" && charAfter === "}") ||
      (charBefore === "[" && charAfter === "]");

    if (isInBrackets) {
      // 在括号中间，创建两行：一行给内容，一行给闭括号
      const newIndent = indent + "  "; // 内容缩进
      const newValue =
        value.substring(0, start) +
        "\n" +
        newIndent +
        "\n" +
        indent +
        value.substring(start);
      textarea.value = newValue;
      // 将光标定位到内容行
      textarea.selectionStart = textarea.selectionEnd =
        start + 1 + newIndent.length;
      jsonText.value = newValue;
    } else {
      // 普通回车处理
      // 如果当前行以{或[结尾，增加缩进
      const extraIndent = /[{\[]\s*$/.test(currentLine.trim()) ? "  " : "";

      const newValue =
        value.substring(0, start) +
        "\n" +
        indent +
        extraIndent +
        value.substring(start);
      textarea.value = newValue;
      textarea.selectionStart = textarea.selectionEnd =
        start + 1 + indent.length + extraIndent.length;
      jsonText.value = newValue;
    }
  }
};

// JSON操作方法
const formatJson = () => {
  try {
    const parsed = JSON.parse(jsonText.value);
    jsonText.value = JSON.stringify(parsed, null, 2);
    validationMessage.value = t(
      "formDesigner.propertyPanel.common.formatSuccess"
    );
    validationClass.value = "success";
    setTimeout(() => {
      validationMessage.value = "";
    }, 2000);
  } catch (error) {
    validationMessage.value =
      t("formDesigner.propertyPanel.common.validateError") +
      "：" +
      error.message;
    validationClass.value = "error";
  }
};

const compressJson = () => {
  try {
    const parsed = JSON.parse(jsonText.value);
    jsonText.value = JSON.stringify(parsed);
    validationMessage.value = t(
      "formDesigner.propertyPanel.common.compressSuccess"
    );
    validationClass.value = "success";
    setTimeout(() => {
      validationMessage.value = "";
    }, 2000);
  } catch (error) {
    validationMessage.value =
      t("formDesigner.propertyPanel.common.validateError") +
      "：" +
      error.message;
    validationClass.value = "error";
  }
};

const validateJson = () => {
  try {
    JSON.parse(jsonText.value);
    validationMessage.value = t(
      "formDesigner.propertyPanel.common.validateSuccess"
    );
    validationClass.value = "success";
    setTimeout(() => {
      validationMessage.value = "";
    }, 2000);
  } catch (error) {
    validationMessage.value =
      t("formDesigner.propertyPanel.common.validateError") +
      "：" +
      error.message;
    validationClass.value = "error";
  }
};

// 重置为示例数据
const resetTreeData = () => {
  let defaultData = [];
  if (props.treeType === "tree") {
    defaultData = [
      {
        id: 1,
        label: `${t("formDesigner.propertyPanel.common.exampleLevel1")} 1`,
        children: [
          {
            id: 4,
            label: `${t(
              "formDesigner.propertyPanel.common.exampleLevel2"
            )} 1-1`,
            children: [
              {
                id: 9,
                label: `${t(
                  "formDesigner.propertyPanel.common.exampleLevel3"
                )} 1-1-1`,
              },
              {
                id: 10,
                label: `${t(
                  "formDesigner.propertyPanel.common.exampleLevel3"
                )} 1-1-2`,
              },
            ],
          },
        ],
      },
      {
        id: 2,
        label: `${t("formDesigner.propertyPanel.common.exampleLevel1")} 2`,
        children: [
          {
            id: 5,
            label: `${t(
              "formDesigner.propertyPanel.common.exampleLevel2"
            )} 2-1`,
          },
          {
            id: 6,
            label: `${t(
              "formDesigner.propertyPanel.common.exampleLevel2"
            )} 2-2`,
          },
        ],
      },
      {
        id: 3,
        label: `${t("formDesigner.propertyPanel.common.exampleLevel1")} 3`,
        children: [
          {
            id: 7,
            label: `${t(
              "formDesigner.propertyPanel.common.exampleLevel2"
            )} 3-1`,
          },
          {
            id: 8,
            label: `${t(
              "formDesigner.propertyPanel.common.exampleLevel2"
            )} 3-2`,
          },
        ],
      },
    ];
  } else if (props.treeType === "treeSelect" || props.treeType === "cascader") {
    defaultData = [
      {
        value: "1",
        label: `${t("formDesigner.propertyPanel.common.exampleLevel1")} 1`,
        children: [
          {
            value: "1-1",
            label: `${t(
              "formDesigner.propertyPanel.common.exampleLevel2"
            )} 1-1`,
            children: [
              {
                value: "1-1-1",
                label: `${t(
                  "formDesigner.propertyPanel.common.exampleLevel3"
                )} 1-1-1`,
              },
            ],
          },
        ],
      },
      {
        value: "2",
        label: `${t("formDesigner.propertyPanel.common.exampleLevel1")} 2`,
        children: [
          {
            value: "2-1",
            label: `${t(
              "formDesigner.propertyPanel.common.exampleLevel2"
            )} 2-1`,
          },
          {
            value: "2-2",
            label: `${t(
              "formDesigner.propertyPanel.common.exampleLevel2"
            )} 2-2`,
          },
        ],
      },
    ];
  } else if (props.treeType === "descriptions") {
    defaultData = [
      {
        label: t("formDesigner.propertyPanel.descriptions.exampleUsername"),
        value: t(
          "formDesigner.propertyPanel.descriptions.exampleUsernameValue"
        ),
        span: 1,
      },
      {
        label: t("formDesigner.propertyPanel.descriptions.examplePhone"),
        value: t("formDesigner.propertyPanel.descriptions.examplePhoneValue"),
        span: 1,
      },
      {
        label: t("formDesigner.propertyPanel.descriptions.exampleAddress"),
        value: t("formDesigner.propertyPanel.descriptions.exampleAddressValue"),
        span: 2,
        align: "left",
      },
      {
        label: t("formDesigner.propertyPanel.descriptions.exampleRemark"),
        value: t("formDesigner.propertyPanel.descriptions.exampleRemarkValue"),
        span: 3,
      },
    ];
  }

  jsonText.value = JSON.stringify(defaultData, null, 2);
};

// 事件处理
const handleCancel = () => {
  emit("update:modelValue", false);
};

const handleSave = () => {
  try {
    const parsedData = JSON.parse(jsonText.value);
    if (!Array.isArray(parsedData)) {
      ElMessage.error(t("formDesigner.propertyPanel.common.dataFormatError"));
      return;
    }
    emit("save", parsedData, props.treeType);
    emit("update:modelValue", false);
    ElMessage.success(t("formDesigner.propertyPanel.common.saveSuccess"));
  } catch (error) {
    ElMessage.error(t("formDesigner.propertyPanel.common.jsonFormatError"));
  }
};
</script>

<style lang="less" scoped>
/* 树形数据编辑器样式 */
.tree-data-editor {
  .editor-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;

    .editor-title {
      font-weight: 500;
      color: var(--el-text-color-primary);
    }
  }

  .editor-content {
    .data-format-tip {
      background-color: var(--el-fill-color-lighter);
      border: 1px solid var(--el-border-color-light);
      border-radius: 4px;
      padding: 16px;
      font-size: 13px;

      h4 {
        margin: 0 0 12px 0;
        color: var(--el-text-color-primary);
        font-size: 14px;
      }

      p {
        margin: 6px 0;
        color: var(--el-text-color-regular);
        line-height: 1.5;

        :deep(code) {
          background-color: var(--el-fill-color-light);
          padding: 2px 4px;
          border-radius: 3px;
          font-family: "Courier New", monospace;
          font-size: 12px;
          color: var(--el-color-danger);
        }
      }

      .format-example {
        background-color: var(--el-fill-color-dark);
        color: var(--el-text-color-primary);
        padding: 12px;
        border-radius: 4px;
        font-family: "Courier New", monospace;
        font-size: 12px;
        line-height: 1.4;
        margin: 8px 0 0 0;
        overflow-x: auto;
      }
    }

    .json-editor-container {
      display: flex;
      border: 1px solid var(--el-border-color);
      border-radius: 4px;
      overflow: hidden;
      height: 400px;
      background-color: var(--el-bg-color);
    }

    .line-numbers {
      background-color: var(--el-fill-color-lighter);
      border-right: 1px solid var(--el-border-color-light);
      padding: 8px 4px;
      font-family: "Consolas", "Monaco", "Courier New", monospace;
      font-size: 13px;
      line-height: 1.4;
      color: var(--el-text-color-placeholder);
      user-select: none;
      overflow: hidden;
      width: 40px;
      text-align: right;
    }

    .line-number {
      height: 18.2px;
      padding-right: 8px;
    }

    .json-textarea {
      flex: 1;
      border: none;
      outline: none;
      padding: 8px 12px;
      font-family: "Consolas", "Monaco", "Courier New", monospace;
      font-size: 13px;
      line-height: 1.4;
      background-color: transparent;
      color: var(--el-text-color-primary);
      resize: none;
      overflow-y: auto;
    }

    .json-textarea::placeholder {
      color: var(--el-text-color-placeholder);
    }

    .tree-data-textarea {
      font-family: "Courier New", monospace;
      font-size: 13px;

      :deep(.el-textarea__inner) {
        font-family: "Courier New", monospace;
        font-size: 13px;
        line-height: 1.4;
      }
    }

    .json-validation {
      margin-top: 4px;
      padding: 4px 8px;
      border-radius: 4px;
      font-size: 12px;

      &.success {
        background-color: var(--el-color-success-light-9);
        border: 1px solid var(--el-color-success-light-5);
        color: var(--el-color-success);
      }

      &.error {
        background-color: var(--el-color-error-light-9);
        border: 1px solid var(--el-color-error-light-5);
        color: var(--el-color-error);
      }
    }
  }
}
</style>
